use sqlx::{PgPool, Error};
use struct_field_names_as_array::FieldNamesAsSlice;

use crate::core::psqlx_tools::SqlString;
use crate::model::collect::CollectModel;
use crate::model::collect_type::CollectTypeModel;
use crate::model::model::Model;
use crate::types::frontend::collect_type::{CollectListResp, CollectRow, CollectTypeRow, SwReq};


pub struct CollectService;

impl CollectService {
    /// 获取分类列表
    pub async fn get_types(db: &PgPool) -> Result<Vec<CollectTypeRow>, Error> {
        let model = CollectTypeModel::new();
        
        let sql = SqlString::new(model.table())
        .field_slice(CollectTypeRow::FIELD_NAMES_AS_SLICE)
        .order_asc(model.primary_key())
        .select();

        let res = sqlx::query_as::<_, CollectTypeRow>(&sql)
        .fetch_all(db)
        .await;
        
        res
        
    }

    /// 获取收藏列表
    pub async fn get_collects(db: &PgPool, args: &SwReq) -> Result<Vec<CollectListResp>, Error> {
        let is_show = args.sw.unwrap_or(1);
        // 先获取所有
        let model = CollectTypeModel::new();
        
        let sql = SqlString::new(model.table())
        .field_slice(CollectTypeRow::FIELD_NAMES_AS_SLICE)
        .order_asc(model.primary_key())
        .select();

        let res = sqlx::query_as::<_, CollectTypeRow>(&sql)
        .fetch_all(db)
        .await;
        
        let types = match res {
            Ok(data) => data,
            Err(e) => {
                return Err(e)
            }
        };

        // 没有分类，则表示没有数据
        if types.len() == 0 {
            return Ok(Vec::new())
        }

        let mut list:Vec<CollectListResp> = Vec::new();
        let model = CollectModel::new();
        for data in types {
            let sql = SqlString::new(model.table())
            .field_slice(CollectRow::FIELD_NAMES_AS_SLICE)
            .where_eq(model.tid())
            .where_eq(model.is_show())
            .select();

            let res = sqlx::query_as::<_, CollectRow>(&sql)
            .bind(data.id)
            .bind(is_show)
            .fetch_all(db)
            .await;
            let collects = match res {
                Ok(col_data) => col_data,
                Err(_) => {Vec::new()}
            };
            let collect_row = CollectListResp {
                id: data.id,
                name: data.name, 
                collects
            };
            list.push(collect_row);
        }
       
        Ok(list)
        
    }
}
    